package com.BlogPark.controller;

import com.BlogPark.common.utis.CaptchaGenerator;
import com.BlogPark.common.utis.MD5Utils;
import com.BlogPark.common.utis.RandomValidateCode;
import com.BlogPark.common.utis.SendMail;
import com.BlogPark.controller.result.Result;
import com.BlogPark.pojo.User;
import com.BlogPark.service.LoginService.LoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpRequest;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import sun.misc.BASE64Encoder;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.*;

import static com.BlogPark.controller.exception.Code.*;

/**
 * UserController
 * 登录，注册，找回密码，验证
 * 修改用户名与密码
 */
@RestController
@RequestMapping("/user")
public class LoginController {
    private static String vcode;
    //不区分大小写
    private static String lowerCase;
    @Autowired
    private LoginService loginService;

    /**
     * 登录
     *
     * @param reqMap
     * @param request
     * @return
     */
    @PostMapping("/login")
    public Result login(@RequestBody Map<String, Object> reqMap, HttpServletRequest request) {
        String username = reqMap.get("username").toString();
        String password = reqMap.get("password").toString();
        String validate = reqMap.get("validate").toString();
        String msg = null;
        Result result = new Result();
        User user = new User();
        user.setUsername(username);
        user.setPassword(password);

        //校验 验证码
        if (!(validate.equals(lowerCase))) {
            msg = "验证码错误";
            result.setMsg(msg);
        } else {
            try {
                User loginUser = loginService.Login(user);
                System.out.println(loginUser);
                if (loginUser != null && loginUser.getCheckuser() == 1) {
                    String email = loginUser.getEmail();
                    loginService.statusOn(email);
                    User onUser = loginService.getUserByEmail(email);
                    msg = "登录成功";
                    result.setMsg(msg);
                    result.setCode(GET_OK);
                    result.setData(onUser.getId());
                    //登录成功重定向需求方法
                    request.getSession().setAttribute("loginUser", onUser);
                } else if (loginUser != null && loginUser.getCheckuser() == 0) {
                    msg = "您还未激活，请注册激活";
                    result.setMsg(msg);
                    result.setCode(GET_OK);
                    result.setData(null);
                } else {
                    msg = "登录失败";
                    result.setMsg(msg);
                    result.setCode(GET_ERR);
                    result.setData(null);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        return result;
    }

    /**
     * 退出登录
     *
     * @param request
     * @return
     */
    @PostMapping("/logout")
    public Result logout(HttpServletRequest request) {
        HttpSession session = request.getSession();
        User loginUser = (User) session.getAttribute("loginUser");
        loginService.statusOff(loginUser.getEmail());
        request.getSession().removeAttribute("loginUser");
        return new Result("退出成功");
    }



    /**
     * 验证码base64
     *
     * @param request
     * @param response
     * @throws Exception
     */
    @GetMapping("/checkCodeBase64")
    public Result imagecode(HttpServletRequest request, HttpServletResponse response) throws Exception {
        CaptchaGenerator vcg = new CaptchaGenerator();
        Result result = new Result();
        vcode = vcg.generatorVCode();
        lowerCase = vcode.toLowerCase();
        System.out.println(vcode);
        BufferedImage vcodeImage = vcg.generatorVCodeImage(vcode, true);
        response.setDateHeader("Expires", 0);
        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");
        response.setHeader("Pragma", "no-cache");
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        response.addHeader("code", vcode.toLowerCase());
        try {
            ImageIO.write(vcodeImage, "png", outputStream);
            BASE64Encoder encoder = new BASE64Encoder();
            String base64 = encoder.encodeBuffer(outputStream.toByteArray()).trim();
            base64 = base64.replaceAll("\n", "").replaceAll("\r", "");
            Object code = "data:image/jpg;base64," + base64;
            result.setData(code);
            result.setMsg("成功");
            result.setCode(GET_OK);
        } catch (IOException e) {
        } finally {
            if (outputStream != null) {
                outputStream.flush();
                outputStream.close();
            }
        }
        return result;
    }



    /**
     * 修改用户名和密码
     * 用户自定义
     *
     * @param user
     * @return
     */
    @PutMapping("/edit/")
    public Result updateUser(@RequestBody User user) {
        String msg = null;
        Result result = new Result();
        String password = user.getPassword();
        String md5Pwd = MD5Utils.getMd5(password); //加密
        user.setPassword(md5Pwd);
        int i = loginService.updateUser(user);
        if (i > 0) {
            msg = "修改成功";
            result.setMsg(msg);
            result.setCode(UPDATE_OK);
            result.setData(user);
        } else {
            msg = "修改失败";
            result.setMsg(msg);
            result.setCode(UPDATE_ERR);
            result.setData(user);
        }
        return result;
    }


    /**
     * 邮箱找回密码
     * 暂时没删除
     *
     * @param request
     * @param email
     * @param model
     * @return
     */
    @GetMapping("/forget_pwd")
    public Result forgetPass(HttpServletRequest request, @RequestParam("email") String email, Model model) {
        User user = loginService.findUserByEmail(email);
        Result result = new Result();
        String msg = "";
        if (email.equals("")) {              //用户名不存在
            msg = "请输入邮箱！";
            result.setMsg(msg);
            result.setCode(GET_ERR);
        }
        if (user == null) {              //用户不存在
            msg = "Email未注册,你这小可爱(tm)是不是记错了?!";
            result.setCode(GET_ERR);
            result.setMsg(msg);
        } else {
            try {
                //生成新的密码
                String pwd = CaptchaGenerator.generatorPwdAndUser(8);
                String md5pwd = MD5Utils.getMd5(pwd);
                user.setPassword(md5pwd);
                loginService.updateUser(user); //保存到数据库
                String emailContent = "请勿回复本邮件<br/>"
                        + "tips:您正在进行的操作是：找回密码<br/>" + "您的账户为：" + user.getUsername() + "\n" + "密码为：" + pwd;
                //调用工具类里面的发送发放
                SendMail sendMail = new SendMail();
                sendMail.sendMail(user.getEmail(), emailContent);
                msg = "操作成功,已发送找回密码链接到您邮箱,请注意查收";
            } catch (Exception e) {
                e.printStackTrace();
                msg = "邮箱不存在？";
            }
        }
        result.setMsg(msg);
        result.setCode(GET_OK);
        result.setData(user);
        return result;
    }

    /**
     * 检车邮箱链接
     *
     * @param sid
     * @param email
     * @param model
     * @return
     */
    @GetMapping("/resetPwdCheck")
    public Result checkResetLink(@RequestParam("sid") String sid, @RequestParam("email") String email, Model model) {
        System.out.println("sid:" + sid + "\n" + "email:" + email);
        Result result = new Result();
        String msg = "";
        String msg2 = "";
        if (sid.equals("") || email.equals("")) {
            msg = "链接不完整,请重新生成";
            model.addAttribute("msg", msg);
            msg2 = "findEmailError";
            result.setMsg(msg2);
            result.setData(model);
            result.setCode(GET_ERR);

        }

        User user = loginService.findUserByEmail(email);
        if (user == null) {
            msg = "链接错误,无法找到匹配用户,请重新申请找回密码.";
            model.addAttribute("msg", msg);
            msg2 = "findEmailError";
            result.setMsg(msg2);
            result.setData(model);
            result.setCode(GET_ERR);
        }
        Date outDate = user.getOutdate();
        if (outDate.getTime() <= System.currentTimeMillis()) {         //表示已经过期
            msg = "链接已经过期,请重新申请找回密码.";
            model.addAttribute("msg", msg);
            msg2 = "findEmailError";
            result.setMsg(msg2);
            result.setData(model);
            result.setCode(GET_ERR);
        }
        String key = user.getEmail() + "$" + outDate.getTime() / 1000 * 1000 + "$" + user.getValidatacode();          //数字签名
        String digitalSignature = MD5Utils.getMd5(key);

        System.out.println(key + "\t" + digitalSignature);

        if (!digitalSignature.equals(sid)) {
            msg = "链接不正确,是否已经过期了?请重新申请";
            model.addAttribute("msg", msg);
            msg2 = "findEmailError";
            result.setMsg(msg2);
            result.setData(model);
            result.setCode(GET_ERR);
        }
        model.addAttribute("email", email);
        msg = "成功";
        result.setMsg(msg);
        result.setCode(GET_OK);
        result.setData(model);
        return result;

    }


    /**
     * 跳转页，用户重置密码
     *
     * @param model
     * @param user
     * @return
     */
    @PutMapping("/resetPwd")
    public Result resetPwd(Model model, @RequestBody User user) {
        String email = user.getEmail();
        String msg = "";
        Result result = new Result();
        User newUser = loginService.findUserByEmail(email);
        String password = user.getPassword();
        newUser.setPassword(MD5Utils.getMd5(password));
        int i = loginService.updatePWD(newUser);
        if (i > 0) {

            msg = "重置成功";
            result.setMsg(msg);
            result.setCode(UPDATE_OK);
            result.setData(newUser);
        } else {

            msg = "重置失败";
            result.setMsg(msg);
            result.setCode(UPDATE_ERR);
            result.setData(newUser);
        }
        return result;
    }


}
